package com.yanxml.core.java.reference.soft_reference;

import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.util.HashSet;
import java.util.Set;

public class SoftReferenceTest_ReferenceQueue {

    public static int removedSoftRefs = 0;

    public static class MyBigObject {
        int[] data = new int[128];
    }

    public static int CACHE_INITIAL_CAPACITY = 100_000;
    // 静态集合保存软引用，会导致这些软引用对象本身无法被垃圾回收器回收
    public static Set<SoftReference<MyBigObject>> cache = new HashSet<>(CACHE_INITIAL_CAPACITY);
    public static ReferenceQueue<MyBigObject> referenceQueue = new ReferenceQueue<>();

    public static void clearUselessReferences() {
        Reference<? extends MyBigObject> ref = referenceQueue.poll();
        while (ref != null) {
            if (cache.remove(ref)) {
                removedSoftRefs++;
            }
            ref = referenceQueue.poll();
        }
    }

    /**
     * VM Options
     * -Xms4m -Xmx4m -Xmn2m
     */
    public static void main(String[] args) {
        for (int i = 0; i < 100_000; i++) {
            MyBigObject obj = new MyBigObject();
            cache.add(new SoftReference<>(obj, referenceQueue));
            clearUselessReferences();
        }
        System.out.println("End, removed soft references=" + removedSoftRefs);
    }
}
